﻿using GrayParrot.Core.Data;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrayParrot.Data.EntityFramework
{
    public class UnitOfWork : IUnitOfWork
    {
        private DbContext m_context;

        public DbContext Context
        {
            get { return m_context; }
        }

        public UnitOfWork(DbContext context)
        {
            m_context = context;        
        }

        public void SaveChanges()
        {
            if(m_context == null)
                throw new InvalidOperationException("This unit of work has already been saved or undone.");

            try
            {
                m_context.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                // Retrieve the error messages as a list of strings.
                var errorMessages = ex.EntityValidationErrors
                        .SelectMany(x => x.ValidationErrors)
                        .Select(x => x.ErrorMessage);

                // Join the list to a single string.
                var fullErrorMessage = string.Join("; ", errorMessages);

                // Combine the original exception message with the new one.
                var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);

                //GrayParrot.Logging.Logger.For<T>().Error(exceptionMessage, ex);

                // Throw a new DbEntityValidationException with the improved exception message.
                throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
            }
            catch (Exception ex)
            {
                Console.Write(ex);
                //GrayParrot.Logging.Logger.For<T>().Error("Errore in Save", ex);
            }
        }

        public void Dispose()
        {
            if (m_context == null)
                return;

            m_context.Dispose();
        }
    }
}
